/**
  * Author: Mei
  * Date: 2021-01-07 15:20
  * Description: 单例模式改进
  * 主要解决构造函数参数不定的情况，可以使用可变模板参数
  *
  */

#include "../head.h"

template<typename T>
class Singleton {
public:
    template<typename ...Args>
    static T *Instance(Args &&...args) { //使用可变模板参数创建对象
        if (m_pInstance == nullptr) {
            m_pInstance = new T(forward<Args>(args)...); //使用完美转发
        }
        return m_pInstance;
    }

    //获取单例
    static T *GetInstance() {
        if (m_pInstance == nullptr) {
            throw logic_error("the instance is not init, please initialize the instance first");
        }
        return m_pInstance;
    }

    static void DestoryInstance() {
        delete m_pInstance;
        m_pInstance = nullptr;
    }

private:
    Singleton(void);

    virtual ~Singleton(void);

    Singleton(const Singleton &);

    Singleton &operator=(const Singleton &);

private:
    static T *m_pInstance; //返回创建的实例对象 必须在外面进行初始化
};

template<typename T>
T *Singleton<T>::m_pInstance = nullptr;

//测试
struct A {
    A(const string &) {
        cout << "lvalue" << endl;
    }

    A(string &&x) {
        cout << "rvalue" << endl;
    }
};

struct C {
    C(int x, int y) {
    }

    void Func() {
        cout << "test" << endl;
    }
};

int main() {
    string str = "abc";
    Singleton<A>::Instance("cc");

    Singleton<C>::Instance(20, 30);
    Singleton<C>::GetInstance()->Func();

    return 0;
}